import go from 'gojs'
/*
 *  Copyright (C) 1998-2018 by Northwoods Software Corporation. All Rights Reserved.
 */

// A custom LinkReshapingTool that shows only a single reshape handle on a Bezier curved Link.
// Dragging that handle changes the value of {@link Link#curviness}.

/**
 * @constructor
 * @extends LinkReshapingTool
 * @class
 * This CurvedLinkReshapingTool class allows for a Link's path to be modified by the user
 * via the dragging of a single tool handle at the middle of the link.
 */
function CurvedLinkReshapingTool() {
  go.LinkReshapingTool.call(this)
  /** @type {number} */
  this._originalCurviness = NaN
}
go.Diagram.inherit(CurvedLinkReshapingTool, go.LinkReshapingTool)

/**
 * @override
 * @this {CurvedLinkReshapingTool}
 * @param {Shape} pathshape
 * @return {Adornment}
 */
CurvedLinkReshapingTool.prototype.makeAdornment = function(pathshape) {
  const link = pathshape.part
  // console.log(link.data.category);
  if (
    link !== null &&
    link.curve === go.Link.Bezier &&
    link.pointsCount === 4
  ) {
    const adornment = new go.Adornment()
    adornment.type = go.Panel.Link
    const h = this.makeHandle()
    this.setReshapingBehavior(h, go.LinkReshapingTool.All)
    h.cursor = 'move'
    adornment.add(h)
    adornment.category = this.name
    adornment.adornedObject = pathshape
    return adornment
  } else {
    return go.LinkReshapingTool.prototype.makeAdornment.call(this, pathshape)
  }
}

/**
 * @override
 * @this {CurvedLinkReshapingTool}
 */
CurvedLinkReshapingTool.prototype.doActivate = function() {
  go.LinkReshapingTool.prototype.doActivate.call(this)
  this._originalCurviness = this.adornedLink.curviness
}

/**
 * @override
 * @this {CurvedLinkReshapingTool}
 */
CurvedLinkReshapingTool.prototype.doCancel = function() {
  this.adornedLink.curviness = this._originalCurviness
  go.LinkReshapingTool.prototype.doCancel.call(this)
}

/**
 * @override
 * @this {CurvedLinkReshapingTool}
 * @param {Point} newpt
 * @return {Point}
 */
CurvedLinkReshapingTool.prototype.reshape = function(newpt) {
  const link = this.adornedLink
  // console.log(link.data);
  if (
    link !== null &&
    link.curve === go.Link.Bezier &&
    link.pointsCount === 4
  ) {
    const start = link.getPoint(0)
    const end = link.getPoint(3)
    const ang = start.directionPoint(end)
    const mid = new go.Point((start.x + end.x) / 2, (start.y + end.y) / 2)
    const a = new go.Point(9999, 0).rotate(ang + 90).add(mid)
    const b = new go.Point(9999, 0).rotate(ang - 90).add(mid)
    const q = newpt.copy().projectOntoLineSegmentPoint(a, b)
    let curviness = Math.sqrt(mid.distanceSquaredPoint(q))
    if (link.fromPort === link.toPort) {
      if (newpt.y < link.fromPort.getDocumentPoint(go.Spot.Center).y) {
        curviness = -curviness
      }
    } else {
      const diff = mid.directionPoint(q) - ang
      if ((diff > 0 && diff < 180) || diff < -180) {
        curviness = -curviness
      }
    }
    link.curviness = curviness
    return q
  } else {
    go.LinkReshapingTool.prototype.reshape.call(this, newpt)
  }
}

export default CurvedLinkReshapingTool
